#ifndef __CZF_EDITSTACK_H__
#define __CZF_EDITSTACK_H__

enum EditOpCode { NotDefined = 0, Add, Remove};

class CTextDoc;

class CEditOperation
{
public:
    CEditOperation();
    virtual ~CEditOperation();

    // Returns 0 on success, -1 if out of memory.
    int CopyString(const char* src);

    unsigned int m_startline;
    unsigned int m_startcol;
    unsigned int m_endline;
    unsigned int m_endcol;
    unsigned int m_uID;
    char* m_text;
    EditOpCode m_operation;   
};

class CEditStack
{
public:
    CEditStack();
    virtual ~CEditStack();

    int SetStackSize(unsigned int nCount);
    void SetDocument(CTextDoc* doc);
    int AddOperation (CEditOperation* op);
    void StartTransaction();
    void EndTransaction();
    int ReDoCurOperations(unsigned int *rowCursor, unsigned int *colCursor);
    int UnDoCurOperations(unsigned int *rowCursor, unsigned int *colCursor);
    void ClearAll();

protected:
    int MoveCurPosForward();
    int MoveCurPosBackward();
    void RemoveOpsFromStart();
    void MoveEndToCurPos();
    void DeleteOpAt(unsigned int idx);
    // if last_idx == (unsigned int)(-1), GetCurPosOperationForward returns the object pointed by m_uCurPos;
    //  last_idx is updated upon return. 
    //  Call this function, until it returns NULL.
    CEditOperation* GetCurOperationsForward(unsigned int* last_idx);
    // if last_idx == (unsigned int)(-1), GetCurPosOperationBackward returns the object pointed by m_uCurPos;
    //  last_idx is updated upon return. 
    //  Call this function, until it returns NULL.
    CEditOperation* GetCurOperationsBackward(unsigned int* last_idx);
    int ReDoOperation(CEditOperation* op);
    int UnDoOperation(CEditOperation* op);

    // Members for the Circ queue;
    CEditOperation** m_circqueue;
    unsigned int m_uCount;
    unsigned int m_uStart;
    unsigned int m_uEnd;
    unsigned int m_uCurPos;
    bool m_bEmpty;
    unsigned int m_uOperationID;
    bool m_bInTransaction;
    bool m_bFirstInTransaction;
    bool m_bHitStart;

protected:
    CTextDoc* m_doc;    
};
#endif /* __CZF_EDITSTACK_H__ */
